package ua.maxicash.vo;

import org.apache.log4j.Logger;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import javax.persistence.*;
import java.io.IOException;
import java.io.Serializable;
import java.util.Set;

@Entity
@Table(name = "Work")
@JsonIgnoreProperties({"applicants","workLight"})
//@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Work implements Serializable{

    private static final Logger logger = Logger
			.getLogger(Work.class);

	public class WorkLight {

		private Long idWork;
		private JobType jobType;
		private City city;
		private Double wage;
		private String about;
		private String employerEmail;
        private String employerFirstName;
        private String employerLastName;

		public WorkLight() {
		}

		public Long getIdWork() {
			return idWork;
		}

		public void setIdWork(Long idWork) {
			this.idWork = idWork;
		}

        public String getEmployerFirstName() {
            return employerFirstName;
        }

        public void setEmployerFirstName(String employerFirstName) {
            this.employerFirstName = employerFirstName;
        }

        public String getEmployerLastName() {
            return employerLastName;
        }

        public void setEmployerLastName(String employerLastName) {
            this.employerLastName = employerLastName;
        }

        public JobType getJobType() {
			return jobType;
		}

		public void setJobType(JobType jobType) {
			this.jobType = jobType;
		}

		public City getCity() {
			return city;
		}

		public void setCity(City city) {
			this.city = city;
		}

		public Double getWage() {
			return wage;
		}

		public void setWage(Double wage) {
			this.wage = wage;
		}

		public String getAbout() {
			return about;
		}

		public void setAbout(String about) {
			this.about = about;
		}

		public String getEmployerEmail() {
			return employerEmail;
		}

		public void setEmployerEmail(String employerEmail) {
			this.employerEmail = employerEmail;
		}
		
	}

	@Id
	@Column(name = "ID_WORK")
	@GeneratedValue
	private Long idWork;

	@ManyToOne(cascade = { CascadeType.REFRESH })
	@JoinColumn(name = "ID_JOB")
    private JobType jobType;

	@ManyToOne
	@JoinColumn(name = "ID_USER", insertable = true, updatable = true)
	//@org.hibernate.annotations.Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE })
    private Employer employer;

	@OneToMany(fetch = FetchType.EAGER)
	@org.hibernate.annotations.Cascade(value = {
			org.hibernate.annotations.CascadeType.SAVE_UPDATE,
			org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	@JoinColumn(name = "ID_WORK")
   // @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Set<WorkingDay> schedule;

	@ManyToMany
	@JoinTable(name = "Work_Worker", joinColumns = { @JoinColumn(name = "ID_WORK") }, inverseJoinColumns = { @JoinColumn(name = "ID_USER") })
	@LazyCollection(LazyCollectionOption.FALSE)
	@org.hibernate.annotations.Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE })
   // @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Set<Worker> applicants;

	@ManyToOne
	@JoinColumn(name = "id_City")
	private City city;

	@Column(name = "about")
	private String about;

	@Column(name = "wage")
	private Double wage;

	public Long getIdWork() {
		return idWork;
	}

	public void setIdWork(Long idWork) {
		this.idWork = idWork;
	}

	public Employer getEmployer() {
		return employer;
	}

	public void setEmployer(Employer employer) {
		this.employer = employer;
	}

	public JobType getJobType() {
		return jobType;
	}

	public void setJobType(JobType jobType) {
		this.jobType = jobType;
	}

	public String getAbout() {
		return about;
	}

	public void setAbout(String about) {
		this.about = about;
	}

	public Set<WorkingDay> getSchedule() {
		return schedule;
	}

	public void setSchedule(Set<WorkingDay> schedule) {
		this.schedule = schedule;
	}

	public Double getWage() {
		return wage;
	}

	public void setWage(Double wage) {
		this.wage = wage;
	}

	public Set<Worker> getApplicants() {
		return applicants;
	}

	public void setApplicants(Set<Worker> applicants) {
		this.applicants = applicants;
	}

	public City getCity() {
		return city;
	}

	public void setCity(City city) {
		this.city = city;
	}

	public WorkLight getWorkLight() {

		WorkLight wl = this.new WorkLight();
		wl.setAbout(about);
		wl.setCity(city);
		wl.setIdWork(idWork);
		wl.setJobType(jobType);
		wl.setWage(wage);
		wl.setEmployerEmail(employer.getEmail());
        wl.setEmployerFirstName(employer.getFirstName());
        wl.setEmployerLastName(employer.getLastName());

		return wl;
	}

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Work work = (Work) o;

        if (idWork != null ? !idWork.equals(work.idWork) : work.idWork != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return idWork != null ? idWork.hashCode() : 0;
    }

    @Override
	public String toString() {
		return "Work [idWork=" + idWork + ", jobType=" + jobType
				+ ", employer=" + employer + ", schedule=" + schedule
				+ ", about=" + about + "]";
	}

    public String toJSON() {

         ObjectMapper mapper = new ObjectMapper();
        String stringData = null;
        try {
            stringData = mapper.writeValueAsString(this);
            logger.info("data : " + stringData);
        } catch (IOException e) {
            logger.error(e);
        }
        return stringData;
    }

}
